package plugin;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class CompileClassLoader extends ClassLoader{
    /**
     * 字节码文件来源路径
     */
    private String rootDir;

    public CompileClassLoader(String rootDir){
        super();
        this.rootDir = rootDir;
    }

    /**
     * 当父类加载器无法加载指定类时，JVM会调用此方法。
     * @param name 权限定类名
     *
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classBytes = loadClassData(name); // 加载类文件字节码
        if (classBytes == null) {
            throw new ClassNotFoundException(name);
        }

        // 安全地定义类，从给定的字节数组中加载类
        return defineClass(name, classBytes, 0, classBytes.length);
    }

    // 实现从文件系统加载类字节码的方法
    private byte[] loadClassData(String className) {
        String fileName = className.replace('.', '/') + ".class";
        File file = new File(rootDir, fileName);

        try (FileInputStream fis = new FileInputStream(file)) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}
